home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Disk / Directory / window.c < prev   
Encoding:
Text File  |  1993-02-03  |  8.6 KB  |  509 lines  |  [TEXT/KAHL]

  1. //-- Window.c --//
  2.  
  3. // Generic window management routines.
  4.  
  5. // The window management routines to create and distroy drawing windows and their data
  6. // structures, to redraw windows, and to append lines to the window line buffer, as well
  7. // to managing scrolling and such.  This is the total of all the routines to manage windows.
  8. // This also contains the code to manage the project window as such. */
  9.  
  10. #include <stdio.h>
  11. #include "struct.h"
  12. #include "res.h"
  13. #include "error.h"
  14.  
  15. //-- GLOBALS --//
  16.  
  17. //-- The globals used for the window structure.
  18.  
  19. struct DrawWindow *drawList;
  20. static struct DrawWindow *whichScroll;    // What window is being scrolled?
  21. Rect openSize;
  22. extern unsigned char MultiWidget;        // State flags.
  23.  
  24. //-- CODE --//
  25.  
  26. //-- The different routines
  27.  
  28. //-- Basic allocation/deallocation of windows.
  29.  
  30. //-- AllocateWindow --//
  31.  
  32. //-- This allocs a new window.  
  33. //-- WARNING:  Errors are returned using the 'Throw' mechanism.
  34.  
  35. struct DrawWindow *AllocateWindow()
  36. {
  37.     int i;
  38.     
  39.     for (i = 0; i < MAXWINDOWS; i++) if (drawList[i].inuse == 0) break;
  40.     if (i == MAXWINDOWS) Throw(OUTWINDOWS);
  41.  
  42.     drawList[i].inuse = 1;
  43.     openSize.top = 38 + i * 20;
  44.     openSize.left = 30 - i * 3;
  45.     openSize.right = -i * 3;
  46.     openSize.bottom = - 10;
  47.     if (MultiWidget) openSize.right -= 75;
  48.     return &(drawList[i]);
  49. }
  50.  
  51.  
  52. //-- FreeWind
  53.  
  54. // This frees a window.  Only do this AFTER disposing of the window.
  55.  
  56. FreeWind(w)
  57. struct DrawWindow *w;
  58. {
  59.     w->inuse = 0;
  60. }
  61.  
  62. //-- Basic window math. --//
  63.  
  64. //-- CalcScroll --//
  65.  
  66. // Given a window, this computes where the scroll bars are to go..
  67.  
  68. CalcScroll(w,x,y)
  69. WindowPtr w;
  70. Rect *x,*y;
  71. {
  72.     Rect r;
  73.     
  74.     r = w->portRect;
  75.     x->top = r.bottom - 15;
  76.     x->bottom = r.bottom + 1;
  77.     x->right = r.right - 14;
  78.     x->left = -1;
  79.     
  80.     y->top = -1;
  81.     y->bottom = r.bottom - 14;
  82.     y->left = r.right - 15;
  83.     y->right = r.right + 1;
  84. }
  85.  
  86.  
  87. //-- CalcClip --//
  88.  
  89. // Calculate the clip area of the window (where to draw, which doesn't include scroll
  90. // bars.
  91.  
  92. CalcClip(w,c)
  93. WindowPtr w;
  94. Rect *c;
  95. {
  96.     Rect r;
  97.  
  98.     r = w->portRect;
  99.     c->top = r.top;
  100.     c->left = r.left;
  101.     c->right = r.right - 15;
  102.     c->bottom = r.bottom - 15;
  103. }
  104.  
  105. //-- Window management. --//
  106.  
  107.  
  108. //-- NewPlan --//
  109.  
  110. // Open a new window.
  111.  
  112. struct DrawWindow *NewPlan(name)
  113. short name;                                /* vRefNum of this object */
  114. {
  115.     int i;
  116.     struct DrawWindow *w;
  117.     short step;
  118.     GrafPtr foo;
  119.     Rect r;
  120.     Rect s;
  121.     int t;
  122.  
  123. // Step 1:  Prepare for disaster.
  124.     
  125.     step = 1;
  126.     if (i = Catch()) {
  127.     
  128. // According to the step number, do the appropriate shutting down.
  129.  
  130.         switch (step) {
  131.             case 2:
  132.                 CloseWindow(w);
  133.                 FreeWind(w);
  134.             case 1:
  135.                 break;
  136.         }
  137.         
  138. // Post the error message, and return.
  139.  
  140.         PostError(i);
  141.         return NULL;
  142.     }
  143.     
  144. // Step 2:  Allocate and open the window.
  145.  
  146.     w = AllocateWindow();
  147.     GetWMgrPort(&foo);
  148.     r = foo->portRect;
  149.     r.right += openSize.right;
  150.     r.bottom += openSize.bottom;
  151.     r.top = openSize.top;
  152.     r.left = openSize.left;
  153.     InsetRect(&r,4,4);
  154.     NewWindow(w,&r,"\pUntitled",1,8,(char *)-1,CanEject(name),0L);
  155.     step = 2;
  156.     
  157.     /*
  158.      *    Step 3:  Initialize different data structures
  159.      */
  160.  
  161.     w->state = 0;                        /* Directories only */
  162.     w->w.windowKind = WK_PLAN;
  163.     ComputePict(name,w);
  164.  
  165.     CalcScroll(w,&r,&s);
  166.     if (NULL == (w->yScroll = NewControl(w,&s,"",1,0,0,0,16,0L))) 
  167.         Throw(OUTMEM);
  168.     
  169.     t = (GetHandleSize(w->data) / sizeof(struct DirectData)) - 1;
  170.     if (t < 0) t = 0;
  171.     SetCtlMax(w->yScroll,t);
  172.  
  173. // All done.  Return.
  174.     
  175.     Uncatch();
  176.     return w;
  177. }
  178.  
  179.  
  180.  
  181.  
  182. //-- ClosePlan --//
  183.  
  184. // What to do when the 'close' option is selected for a particular plan.
  185.  
  186.  
  187. int ClosePlan(w)
  188. struct DrawWindow *w;
  189. {
  190.  
  191. // Dispose of the window and quit.
  192.  
  193.     if (!CanEject(w->vRefNum)) return 0;    /* Failure */
  194.     Eject("",w->vRefNum);
  195.     UnmountVol("",w->vRefNum);
  196.     DisposHandle(w->data);
  197.     CloseWindow(w);
  198.     FreeWind(w);
  199.     return 1;                                /* Success */
  200. }
  201.  
  202.  
  203.  
  204. //-- UpdatePlan --//
  205.  
  206. // This updates the plan (redraws the contents of the window).
  207.  
  208. UpdatePlan(w)
  209. struct DrawWindow *w;
  210. {
  211.     DrawGrowIcon(w);
  212.     DrawControls(w);
  213.     DrawPlanWind(w);
  214. }
  215.  
  216.  
  217.  
  218. //-- DrawPlanWind --//
  219.  
  220. // Actually draw the contents of this drawing window.
  221.  
  222. DrawPlanWind(w)
  223. struct DrawWindow *w;
  224. {
  225.     int x,y;
  226.     Rect r;
  227.     RgnHandle rgn;
  228.     Rect s;
  229.     long l,i;
  230.     struct DirectData *ptr;
  231.     short ind;
  232.     
  233. //-- Properly initialize clipping for redrawing the screen
  234.  
  235.     SetPort(w);
  236.     CalcClip(w,&r);
  237.     rgn = NewRgn();
  238.     GetClip(rgn);
  239.     ClipRect(&r);
  240.     
  241. //-- Draw the contents of the screen
  242.  
  243.     HLock(w->data);
  244.     ptr = *(w->data);
  245.     TextFont(4);
  246.     TextSize(9);
  247.     y = GetCtlValue(w->yScroll);
  248.     l = GetHandleSize(w->data) / sizeof(struct DirectData);
  249.     for (i = y, x = 12; i < l; i++, x += 12) {
  250.         for (ind = 0; ind < ptr[i].indent; ind++) {
  251.             MoveTo(ind*12+15,x-10);
  252.             Line(0,12);
  253.         }
  254.         MoveTo(ptr[i].indent*12+10,x);
  255.         DrawString(ptr[i].data);
  256.         if (ptr[i].auxdata[0] != '\0') {
  257.             MoveTo(ptr[i].indent*12+15+StringWidth(ptr[i].data),x);
  258.             LineTo(295,x);
  259.             MoveTo(360 - StringWidth(ptr[i].auxdata),x);
  260.             DrawString(ptr[i].auxdata);
  261.             
  262.             MoveTo(380,x);
  263.             DrawString(ptr[i].auxdata2);
  264.         }
  265.         if (x > r.bottom) break;
  266.     }
  267.     HUnlock(w->data);
  268.         
  269. // Reset the clipper properly.
  270.  
  271.     SetClip(rgn);
  272.     DisposeRgn(rgn);
  273. }
  274.  
  275.  
  276.  
  277. //-- ActivatePlan --//
  278.  
  279. // What to do when to activate/deactivate windows.
  280.  
  281. ActivatePlan(w,i)
  282. struct DrawWindow *w;
  283. int i;
  284. {
  285.     SetPort(w);
  286.     DrawGrowIcon(w);
  287.  
  288.     if (!i) {
  289.         HideControl(w->yScroll);
  290.     } else {
  291.         ShowControl(w->yScroll);
  292.     }
  293. }
  294.  
  295.  
  296. //-- ResizeInitPlan --//
  297.  
  298. // Do resizing initialization for the plans.  This is so that the object in the
  299. // centre of the screen remains in the centre.
  300.  
  301. ResizeInitPlan(w)
  302. struct DrawWindow *w;
  303. {
  304.  
  305. // Handle the scroll bars (they should be invisible during movement).
  306.  
  307.     HideControl(w->yScroll);
  308. }
  309.  
  310.  
  311. //-- ResizePlan --//
  312.  
  313. // What to do when the window is resized.
  314.  
  315. ResizePlan(w)
  316. struct DrawWindow *w;
  317. {
  318.     Rect x,y;
  319.  
  320.     SetPort(w);
  321.     
  322. // Resize the scroll bars for display again.
  323.  
  324.     CalcScroll(w,&x,&y);
  325.     MoveControl(w->yScroll,y.left,y.top);
  326.     SizeControl(w->yScroll,y.right - y.left,y.bottom - y.top);
  327.     ShowControl(w->yScroll);
  328.  
  329. // Prevent the scroll bars from flickering.
  330.  
  331.     ValidRect(&x);
  332.     ValidRect(&y);
  333. }
  334.  
  335. //-- ScrollPlan --//
  336.  
  337. // How to scroll the plan window.
  338.  
  339. ScrollPlan(w,yo,yn)
  340. struct DrawWindow *w;
  341. int yo,yn;
  342. {
  343.     Rect r;
  344.     RgnHandle update;
  345.     
  346.     update = NewRgn();
  347.     SetPort(w);
  348.     CalcClip(w,&r);
  349.     ScrollRect(&r,0,12 * (yo - yn),update);
  350.     DisposeRgn(update);
  351.     DrawPlanWind(w);
  352. }
  353.  
  354. //-- MyScrollPlan --//
  355.  
  356. // How scrolling is handled in the end.
  357.  
  358. pascal void MyScrollPlan(c,partCode)
  359. ControlHandle c;
  360. short partCode;
  361. {
  362.     short whichDir;
  363.     short delta;
  364.     Rect r;
  365.     int oldval,newval;
  366.     int pin;
  367.  
  368.     r = whichScroll->w.port.portRect;
  369.     whichDir = 0;
  370.  
  371.     switch (partCode) {
  372.         case inUpButton:
  373.             delta = 1;
  374.             break;
  375.         case inPageUp:
  376.             delta = (r.bottom - r.top - 5) / 12;
  377.             break;
  378.         case inDownButton:
  379.             delta = -1;
  380.             break;
  381.         case inPageDown:
  382.             delta = - (r.bottom - r.top - 5) / 12;
  383.             break;
  384.         default:
  385.             delta = 0;
  386.             break;
  387.     }
  388.  
  389.     oldval = GetCtlValue(c);
  390.     newval = oldval - delta;
  391.     if (newval > (pin = GetCtlMax(c))) newval = pin;
  392.     if (newval < (pin = GetCtlMin(c))) newval = pin;
  393.     if (newval == oldval) return;
  394.  
  395.     
  396.     SetCtlValue(c,newval);
  397.     ScrollPlan(whichScroll,oldval,newval);
  398. }
  399.  
  400.  
  401.  
  402. //-- MousePlan --//
  403.  
  404. // What to do when the mouse goes down in the window.
  405.  
  406. MousePlan(w,e,p)
  407. struct DrawWindow *w;
  408. EventRecord *e;
  409. Point *p;
  410. {
  411.     int i;
  412.     ControlHandle c;
  413.     int oldval,newval;
  414.  
  415.     i = FindControl(*p,w,&c);
  416.     if (i) {                            /* down in a control:  scroll bar? */
  417.         SetPort(w);
  418.         if (i == inThumb) {
  419.             oldval = GetCtlValue(c);
  420.             TrackControl(c,*p,NULL);
  421.             newval = GetCtlValue(c);
  422.             ScrollPlan(w,oldval,newval);
  423.         } else {
  424.             whichScroll = w;
  425.             TrackControl(c,*p,MyScrollPlan);
  426.         }
  427.     } else {
  428.     }
  429. }
  430.  
  431.  
  432. //-- SetBtn --//
  433.  
  434. // Set button.
  435.  
  436. SetBtn(dlog,i,val)
  437. DialogPtr dlog;
  438. int i;
  439. int val;
  440. {
  441.     short i1;
  442.     Handle i2;
  443.     Rect i3;
  444.  
  445.     GetDItem(dlog,i,&i1,&i2,&i3);
  446.     SetCtlValue(i2,val);
  447. }
  448.  
  449.  
  450. //-- OptionDialog --//
  451.  
  452. // Set options.
  453.  
  454. OptionDialog()
  455. {
  456.     DialogPtr dlog;
  457.     short i1;
  458.     Handle i2;
  459.     Rect i3;
  460.     short x;
  461.     short nv;
  462.     short t;
  463.     short index;
  464.     struct DrawWindow *w;
  465.     
  466.     w = (struct DrawWindow *)FrontWindow();
  467.     if (w == NULL) return;                            /* not a window to do this to */
  468.     
  469.     nv = w->state;
  470.     dlog = GetNewDialog(OPTIONDLOG,NULL,(char *)-1);
  471.     SetPort(dlog);
  472.     GetDItem(dlog,1,&i1,&i2,&i3);
  473.     PenSize(3,3);
  474.     InsetRect(&i3,-4,-4);
  475.     FrameRoundRect(&i3,16,16);
  476.  
  477.     SetBtn(dlog,4+nv,1);
  478.     for (;;) {
  479.         ModalDialog(NULL,&x);
  480.         switch (x) {
  481.             case 1:
  482.                 DisposDialog(dlog);
  483.                 if (nv != w->state) {
  484.                     w->state = nv;
  485.  
  486.                     SetPort(w);
  487.                     EraseRect(&(w->w.port.portRect));
  488.                     InvalRect(&(w->w.port.portRect));
  489.                     DisposHandle(w->data);
  490.                     ComputePict(w->vRefNum,w);
  491.                     t = (GetHandleSize(w->data) / sizeof(struct DirectData)) - 1;
  492.                     if (t < 0) t = 0;
  493.                     SetCtlMax(w->yScroll,t);
  494.                 }
  495.                 return;
  496.             case 2:
  497.                 DisposDialog(dlog);
  498.                 return;
  499.             case 4:
  500.             case 5:
  501.             case 6:
  502.                 SetBtn(dlog,4+nv,0);
  503.                 nv = x - 4;
  504.                 SetBtn(dlog,4+nv,1);
  505.                 break;
  506.         }
  507.     }
  508. }
  509.